package com.zerosoft.shuguang.config;

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;
import com.zerosoft.shuguang.dao.GuotaiEventParse;
import com.zerosoft.shuguang.entities.FireAlarm;
import com.zerosoft.shuguang.service.FireAlarmService;
import com.zerosoft.shuguang.service.MqttSendClient;
import com.zerosoft.shuguang.service.SensorDataService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class SerialPortConfig {
    @Resource
    private SensorDataService sensorDataService;

    @Resource
    private FireAlarmService fireAlarmService;

    @Resource
    private MqttSendClient mqttSendClient;

    @Resource
    private SerialPortProperties serialPortProperties;
    private List<SerialPortDataListener> listeners = new ArrayList<>();
//    @Bean
    public SerialPort serialPort(){
        //获取端口
        SerialPort[] serialPorts = SerialPort.getCommPorts();//查找所有串口
        for(SerialPort port:serialPorts){
            System.out.println("Port:"+port.getSystemPortName());//打印串口名称，如COM4
            System.out.println("PortDesc:"+port.getPortDescription());//打印串口类型，如USB Serial
            System.out.println("PortDesc:"+port.getDescriptivePortName());//打印串口的完整类型，如USB-SERIAL CH340(COM4)
        }

        SerialPort serialPort = SerialPort.getCommPort(serialPortProperties.getPort());
        // 配置串口（例如波特率、数据位、停止位等）
        serialPort.setComPortParameters(
                serialPortProperties.getBaudRate(),
                serialPortProperties.getDataBits(),
                serialPortProperties.getStopBits(),
                serialPortProperties.getParity()
        );
        serialPort.setComPortTimeouts(
                SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING,
                serialPortProperties.getReadTimeout(),
                serialPortProperties.getWriteTimeout()
        );
        serialPort.setFlowControl(serialPortProperties.getFlowControl());
        mqttSendClient.connect();
//        mqttSendClient.publish(true,"event/guotai","hello world");
        GuotaiEventParse guotaiEventParse = new GuotaiEventParse();
        try {
            if(serialPort.openPort()){
                // ...
                serialPort.addDataListener(new SerialPortDataListener() {//添加监听器。由于该监听器有两个函数，无法使用Lambda表达式
                    @Override
                    public int getListeningEvents() {
                        // TODO Auto-generated method stub
                        return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;//返回要监听的事件类型，以供回调函数使用。可发回的事件包括：SerialPort.LISTENING_EVENT_DATA_AVAILABLE，SerialPort.LISTENING_EVENT_DATA_WRITTEN,SerialPort.LISTENING_EVENT_DATA_RECEIVED。分别对应有数据在串口（不论是读的还是写的），有数据写入串口，从串口读取数据。如果AVAILABLE和RECEIVED同时被监听，优先触发RECEIVED
                    }
                    @Override
                    public void serialEvent(SerialPortEvent event) {//事件处理函数
                        // TODO Auto-generated method stub
                        String data = "";
                        String realData = "";
                        if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE){
                            return;//判断事件的类型
                        }
                        while(serialPort.bytesAvailable()!=0) {
                            byte[] newData = new byte[serialPort.bytesAvailable()];
                            int numRead = serialPort.readBytes(newData, newData.length);
                            String string = new String(newData);
                            data = data + string;
                            //TODO 转换格式并用MQTT发送出去
                            try {
                                Thread.sleep(20);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }//同样使用循环读取法读取所有数据
                        if(data.length()>=3 && data.substring(0, 2) == "$$")
                        {
                            int dataLength = Integer.parseInt(data.substring(2, 3));
                            realData = data.substring(3, dataLength);
                            guotaiEventParse.setDeviceType(Integer.parseInt(realData.substring(0, 1)));
                            guotaiEventParse.setEventType(Integer.parseInt(realData.substring(1, 2)));
                            guotaiEventParse.setDate(realData.substring(2, 10));
                            guotaiEventParse.setTime(realData.substring(10, 18));
                            guotaiEventParse.setBuild(realData.substring(18, 32));
                            guotaiEventParse.setMachine(realData.substring(32, 36));
                            guotaiEventParse.setEventNumber(realData.substring(36, 50));
                            guotaiEventParse.setPanelTypeName(realData.substring(50, 62));
                            guotaiEventParse.setRoad(realData.substring(62, 69));
                            guotaiEventParse.setPartTypeName(realData.substring(69, 81));
                            guotaiEventParse.setDescription(realData.substring(81, 105));
                            guotaiEventParse.setPosition(realData.substring(105, 121));

                            mqttSendClient.publish(true,"shuguang/event/guotai",guotaiEventParse.parseJson());

                            //TODO: 保存数据库
//                        FireAlarm fireAlarm = new FireAlarm(guotaiEventParse);
//                        fireAlarmService.addFireAlarm(fireAlarm);

                            serialPort.writeBytes("$$".getBytes(), 2);
                        }
                        //由于这里是监听函数，所以也可以不使用循环读取法，在监听器外创建一个全局变量，然后将每次读取到的数据添加到全局变量里
                    }
                });
                // 让程序持续运行
                while (true) {
                    try {
                        Thread.sleep(100); // 防止CPU占用过高
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        System.err.println("监听线程被中断");
                        break;
                    }
                }
            }
            else{
                System.out.println("串口打开失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serialPort.isOpen()) {
                serialPort.closePort();
            }
        }
        return serialPort;
    }

//    @Bean
//    public SerialPortDataListener serialDataListener() {
//        return new SerialPortDataListener() {
//            @Override
//            public int getListeningEvents() {
//                return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
//            }
//
//            @Override
//            public void serialEvent(SerialPortEvent event) {
//                // 处理接收到的数据
//                System.out.println("Received data: " + event.getSerialPort().readString());
//            }
//        };
//    }
//
//    @Bean
//    public void registerListeners(SerialPort serialPort, SerialPortDataListener serialDataListener) {
//        serialPort.addDataListener(serialDataListener);
//    }
}
